package com.wltt.product.ahuthr.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

public class JsonUtil {

    private static final ObjectMapper mapper = new ObjectMapper()
            .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    /**
     * 对象转json
     *
     * @param object 对象
     * @return the string
     */
    public static String toJson(Object object) throws JsonProcessingException {
        return mapper.writeValueAsString(object);
    }

    /**
     * json转对象
     *
     * @param json   json字符串
     * @param tClass 类型
     * @return the string
     */
    public static <T> T toObject(String json, Class<T> tClass) throws JsonProcessingException {
        return mapper.readValue(json, tClass);
    }

    /**
     * 根据路径获取jsonNode
     *
     * @param json     json字符串
     * @param jsonPath 类型
     * @return the string
     */
    public static JsonNode getJsonNode(String json, String jsonPath) throws JsonProcessingException {
        String[] paths = jsonPath.trim().split("\\.");
        JsonNode jsonNode = mapper.readTree(json);
        for (String path : paths) {
            if (path.length() < 1) {
                continue;
            }
            jsonNode = jsonNode.path(path);
            if (null == jsonNode || jsonNode.isNull()) {
                throw new RuntimeException("json节点：" + path + "不存在");
            }
        }
        return jsonNode;
    }

    /**
     * 获取JsonNode的所有key
     *
     * @param jsonNode
     */
    public static List<String> getSubKey(JsonNode jsonNode) throws JsonProcessingException {
        List<String> result = new ArrayList<>();
        if (null == jsonNode || jsonNode.isEmpty()) {
            return result;
        }
        Iterator<String> iterator = jsonNode.fieldNames();
        while (iterator.hasNext()) {
            String key = iterator.next();
            result.add(key);
        }
        return result;
    }

    /**
     * 根据有等级关系的数据生成json
     *
     * @param nodes
     */
    public static String generalJsonFromData(List<Node> nodes, boolean beautify) throws JsonProcessingException {
        if (CollectionUtils.isEmpty(nodes)) {
            return null;
        }

        JsonNode jsonNode = JsonNodeFactory.instance.objectNode();
        List<Node> rootNodes = nodes.stream().filter(node -> null == node.getParentId() || "0".equals(node.getParentId())).collect(Collectors.toList());
        for (Node node : rootNodes) {
            getBodyNode(nodes, node, jsonNode);
        }
        if (beautify) {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
        } else {
            return jsonNode.toString();
        }
    }

    private static void getBodyNode(List<Node> nodes, Node currentNode, JsonNode parentJsonNode) {
        List<Node> subNodes = getSubNodes(nodes, currentNode.getId());

        if (CollectionUtils.isEmpty(subNodes)) {
            // 如果当前参数没有子参数
            String value = currentNode.getValue();
            Class type = currentNode.getType();
            if (type.equals(Integer.class) || type.equals(Byte.class) || type.equals(Short.class)) {
                ((ObjectNode) parentJsonNode).put(currentNode.getName(), Integer.parseInt(value));
            } else if (type.equals(Long.class)) {
                ((ObjectNode) parentJsonNode).put(currentNode.getName(), Long.parseLong(value));
            } else if (type.equals(Float.class) || type.equals(Double.class)) {
                ((ObjectNode) parentJsonNode).put(currentNode.getName(), Double.parseDouble(value));
            } else if (type.equals(List.class)) {
                ((ObjectNode) parentJsonNode).putArray(currentNode.getName());
            } else {
                ((ObjectNode) parentJsonNode).put(currentNode.getName(), value);
            }
        } else {

            // 如果当前参数有子参数
            JsonNode currentJsonNode = JsonNodeFactory.instance.objectNode();
            for (Node subNode : subNodes) {
                if (currentNode.getType().equals(List.class)) {
                    ((ObjectNode) parentJsonNode).putArray(currentNode.getName());
                    getBodyNode(nodes, subNode, currentJsonNode);
                    currentJsonNode.isArray();
                    ((ArrayNode) parentJsonNode.path(currentNode.getName())).add(currentJsonNode);
                } else {
                    getBodyNode(nodes, subNode, currentJsonNode);
                }
            }
            if (!currentNode.getType().equals(List.class)) {
                ((ObjectNode) parentJsonNode).put(currentNode.getName(), currentJsonNode);
            }
        }
    }

    /**
     * 获取子节点
     *
     * @param nodes
     * @param parentId
     */
    private static List<Node> getSubNodes(List<Node> nodes, String parentId) {
        return nodes.stream().filter(node -> parentId.equals(node.getParentId())).collect(Collectors.toList());
    }

    public static class Node {

        String id;
        String parentId;
        String name;
        String value;
        Class type;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getParentId() {
            return parentId;
        }

        public void setParentId(String parentId) {
            this.parentId = parentId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public Class getType() {
            return type;
        }

        public void setType(Class type) {
            this.type = type;
        }
    }

//    public static void main(String[] args) {
//        List<Node> nodes = new ArrayList<>();
//
//        Node node1 = new Node();
//        node1.setId("1");
//        node1.setName("参数1");
//        node1.setValue("参数1的值");
//        node1.setType(String.class);
//        node1.setParentId("0");
//        nodes.add(node1);
//
//        Node node1_1 = new Node();
//        node1_1.setId("1_1");
//        node1_1.setName("参数1_1");
//        node1_1.setValue("参数1_1的值");
//        node1_1.setType(String.class);
//        node1_1.setParentId("1");
//        nodes.add(node1_1);
//
//        Node node1_2 = new Node();
//        node1_2.setId("1_2");
//        node1_2.setName("参数1_2");
//        node1_2.setValue("参数1_2的值");
//        node1_2.setType(Object.class);
//        node1_2.setParentId("1");
//        nodes.add(node1_2);
//
//        Node node1_2_1 = new Node();
//        node1_2_1.setId("1_2_1");
//        node1_2_1.setName("参数1_2_1");
//        node1_2_1.setValue("参数1_2_1的值");
//        node1_2_1.setType(String.class);
//        node1_2_1.setParentId("1_2");
//        nodes.add(node1_2_1);
//
//        Node node1_2_2 = new Node();
//        node1_2_2.setId("1_2_2");
//        node1_2_2.setName("参数1_2_2");
//        node1_2_2.setValue("122");
//        node1_2_2.setType(Integer.class);
//        node1_2_2.setParentId("1_2");
//        nodes.add(node1_2_2);
//
//        Node node1_3 = new Node();
//        node1_3.setId("1_3");
//        node1_3.setName("参数1_3");
//        node1_3.setValue("参数1_3的值");
//        node1_3.setType(List.class);
//        node1_3.setParentId("1");
//        nodes.add(node1_3);
//
//        Node node1_4 = new Node();
//        node1_4.setId("1_4");
//        node1_4.setName("参数1_4");
//        node1_4.setValue("参数1_4的值");
//        node1_4.setType(List.class);
//        node1_4.setParentId("1");
//        nodes.add(node1_4);
//
//        Node node1_4_1 = new Node();
//        node1_4_1.setId("1_4_1");
//        node1_4_1.setName("参数1_4_1");
//        node1_4_1.setValue("141");
//        node1_4_1.setType(Long.class);
//        node1_4_1.setParentId("1_4");
//        nodes.add(node1_4_1);
//
//        Node node1_4_2 = new Node();
//        node1_4_2.setId("1_4_2");
//        node1_4_2.setName("参数1_4_2");
//        node1_4_2.setValue("true");
//        node1_4_2.setType(Boolean.class);
//        node1_4_2.setParentId("1_4");
//        nodes.add(node1_4_2);
//
//        Node node2 = new Node();
//        node2.setId("2");
//        node2.setName("参数2");
//        node2.setValue("参数2的值");
//        node2.setType(String.class);
//        node2.setParentId("0");
//        nodes.add(node2);
//
//        Node node3 = new Node();
//        node3.setId("3");
//        node3.setName("参数3");
//        node3.setValue("参数3的值");
//        node3.setType(String.class);
//        node3.setParentId("0");
//        nodes.add(node3);
//
//        System.out.println(generalJsonFromData(nodes, false));
//        System.out.println(generalJsonFromData(nodes, true));
//    }

    public static void main(String[] args) throws JsonProcessingException {
        String json = "{\n" +
                "    \"id\":1,\n" +
                "    \"userName\":\"用户1\",\n" +
                "    \"userAge\":18,\n" +
                "    \"introduction\":\"我是用户1\",\n" +
                "    \"home\":{\n" +
                "        \"father\":\"父亲\",\n" +
                "        \"mother\":\"母亲\"\n" +
                "    },\n" +
                "    \"hobby\":[\n" +
                "        \"walk\",\n" +
                "        \"run\"\n" +
                "    ]\n" +
                "}";
//        String json = "{\n" +
//                "    \"id\":1,\n" +
//                "    \"userName\":\"用户1\",\n" +
//                "    \"userAge\":18,\n" +
//                "    \"introduction\":\"我是用户1\",\n" +
//                "    \"home\":{\n" +
//                "        \"father\":\"父亲\",\n" +
//                "        \"mother\":\"母亲\"\n" +
//                "    },\n" +
//                "    \"hobby\":[\n" +
//                "    ]\n" +
//                "}";

        System.out.println(json);
        System.out.println(getJsonNode(json, "home.fatr").asText());
        System.out.println(getJsonNode(json, "home.father").asText());
        System.out.println(getJsonNode(json, "userName").asText());
        System.out.println();
        System.out.println(getSubKey(mapper.readTree(json)));

        JsonNode hobbyNode = getJsonNode(json, "hobby");
        System.out.println(hobbyNode.isEmpty());
        System.out.println(hobbyNode.isArray());


        for (JsonNode objNode : hobbyNode) {
            System.out.println(objNode.asText());
        }

        System.out.println("不存在的节点：" + mapper.readTree(json).path("dddfss").isEmpty());
        System.out.println("不存在的节点：" + mapper.readTree(json).path("dddfss").asText());

    }

}
